Repository navigation
NVIDIA DLSS in place of the game's upscale (optional, RTX GPUs) - #850
BlueHeisenberg wants to merge 2 commits into
Conversation
…ze 3D at 3840x2160, and the Resolution row reaching the 3D - Output resolution (host/nn_applet.c, nx2/oot_patches.py apply_output_size): the game's whole frame at 2048x1152 (its own), 2560x1440 or 3840x2160, docked, after a restart (HOS_OUTPUT_RES over it). The display size, the docked size list, the 3D's largest size and the scene's size follow it, and the graphics scale reads x1 for a chosen output; the widescreen picture is made at its height (host/hos_main.c). - 3840x2160 3D at the 4K output: the game's render targets' GPU pool (305 MB, for 2560x1440) ran out and the next target came back null. It grows with the output's pixels (687 MB at 4K; HOS_RT_POOL_MB over it), with the "Graphics" module heap that holds it, that heap's budget check counting its shipped use, and the leftover heap made from it kept at its shipped size. At 2048x1152 and 2560x1440 nothing changes. - Resolution: a fixed scale reaches the 3D (it kept the dynamic path's last one), sent in 1/10000 as the twelfth of the output the game draws at; the row shows the 3D's size for the chosen output, and follows the Output resolution row at once. - Test switches: HOS_RES_LOG (the 3D's scale in the log), RX_VK_SHOT_W/H (the screenshots' size), RX_VK_MENU_SCRIPT (timed menu keys) and RX_VK_MENU_DUMP (each drawing of the menu as a BMP).
…A's DLLs not included) - gpu/vk/vk_dlss.cpp, the DLSS part of vk_draw.cpp, vk/shaders/dlss_*.comp: the gameplay upscale network's place in the frame taken by DLSS, which draws the 3D at the DLSS mode's size and scales it to the output with the game's depth and its camera's motion. Ported from zortos293/Lichii (its Streamline loader, camera motion and their shaders; Lichii credits Duck912's Eglantine work). - NVIDIA Streamline v2.14.16's headers in third_party/streamline (MIT, gpu/PROVENANCE.md). sl.interposer.dll, sl.common.dll, sl.dlss.dll and nvngx_dlss.dll are loaded from a streamline folder beside the game exe, or the NVIDIA app's DLSS; the interposer and the model must carry a valid NVIDIA Corporation signature (WinVerifyTrust). Windows only: elsewhere DLSS is unavailable. - Menu rows DLSS (after a restart), DLSS mode (Ultra Performance .. DLAA, each with its size for the chosen output; it sets the 3D's scale in place of Resolution) and DLSS preset (J..M, at once); RX_DLSS, RX_DLSS_PRESET, RX_DLSS_DIR over them, RX_DLSS_DEBUG for its inputs. The scale sent to the game is for the output it runs at (the window crop). - readme: the rows, where NVIDIA's files come from; the Lichii credit.
|
Tested the same approach on a smaller card, in case it helps: RTX 4050 Laptop (6 GB VRAM), Windows 11, Hookshot v2.0.5, Streamline 2.14.16, DLSS preset K, Resolution 50–67 %. My build is a separate prototype based on the same Lichii path (camera reprojection from cbuf 3, no jitter, depth One thing that may matter for 6 GB cards: VRAM pressure makes Streamline refuse DLSS. With the default budget the game went past what the card allows. The log showed In the Kokiri village, GPU time was ~37 ms/frame (≈22 fps). Capping the texture budget with
One catch: changing Resolution after picking the Low preset sets the preset back to Custom, which drops the VRAM cap. So a user who picks Low and then tunes Resolution loses it without noticing. With DLSS on, it might be worth keeping a VRAM cap on 6 GB cards, or noting it in the readme. Reflex: I also added NVIDIA Reflex through the same Streamline instance:
It runs fine together with frame generation 2x and feels noticeably more responsive. If you're interested, I can port it on top of this PR as a follow-up PR. |
…on top of NotRexed#850's DLSS frame code) A second backend for NotRexed#850's replacement of OoT's gameplay upscale, ported from the FSR 4.1 work on Lichii's OoT branch (madebyjordan/Lichii-Hyrule oot-dev, 7f8ae5b337..c5f2fce17d). It takes the same colour, depth and camera motion as DLSS; DLSS keeps priority when it is on. - vk_fsr4.cpp: AMD's FSR API (FidelityFX SDK 2.4). Only the MIT headers are vendored (third_party/fidelityfx); AMD's signed loader and upscaler DLLs load at run time from RX_FSR4_DIR or beside hookshot.exe. The newest 4.x provider the loader lists is picked explicitly (RDNA 2 and 3 run its INT8 model). LDR, non-linear colour, standard depth. One context per output size, render sizes up to it, so the Resolution row and the game's dynamic resolution need no new context. - Jitter: the game draws without one, so the draws that test or write the scene's depth move by a Halton (2, 3) sub-pixel offset through the viewport, and FSR is told it. The offset is part of the state dyn_pack compares, or a frame whose draws match the last frame's would keep the old one. From Lichii: the phase moves on at the network's pass (where the game's frame ends), not at presents; it is on only while FSR drew the last network pass. - AMD edge line (Lichii, RX 6700 XT): moved up or left, the AMD driver draws nothing into the scene's last column or row, a stale near-white value that became a flickering line in FSR's history. FSR's colour and the motion's depth repeat the column and row before them. Colour going into FSR is cleaned of NaN and Inf and clamped to [0, 1]; the output pass drops NaN and Inf for both upscalers. - FSR history resets when FSR did not draw the last network pass or on a camera cut, not by present count. - Menu: "AMD FSR 4.1" (Off/On, at once; ini key fsr4, RX_FSR4=0/1). Resolution sets what it upscales from (75% Quality, 50% Performance, 100% anti-aliasing only). RX_FSR4_JITTER=0 turns the jitter off. - What changes on native, compared with Lichii: no GPU-time divisor (Hookshot already scales the game's timer, so it keeps full quality), no hunt for the tonemap draw or depth reader (NotRexed#818 takes them where the draws are), no 4/3-only size check. - tests/test_fsr_jitter.py: the jitter is compared and applied, moves on at the network's pass, and the edge repeat is in both passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… images given back - The FSR context is made with FFX_UPSCALE_ENABLE_DYNAMIC_RESOLUTION: the render size changes under it with the Resolution row and the game's dynamic resolution. - vk_fsr4.cpp is Windows only (AMD's signed runtime is), with stubs elsewhere: the Linux build has no LoadLibraryExA. - AMD's dispatches count as work (note_work, vk_work.h), so full_barrier does not leave out the barrier after them as a repeat. - dlss_image gives a replaced image back 120 presents later, as typed_upscale does with its histories, instead of keeping it: DLSS fixes the render size, but FSR can run with Resolution Auto. - The dlss_*.comp headers regenerated at SPIR-V 1.6, as NotRexed#850 makes them. - readme: FSR 4 claims limited to what was tested (RX 6700 XT, INT8). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Closing to keep the queue clear — please rebase on current main and reopen; thanks! |
…on top of NotRexed#850's DLSS frame code) A second backend for NotRexed#850's replacement of OoT's gameplay upscale, ported from the FSR 4.1 work on Lichii's OoT branch (madebyjordan/Lichii-Hyrule oot-dev, 7f8ae5b337..c5f2fce17d). It takes the same colour, depth and camera motion as DLSS; DLSS keeps priority when it is on. - vk_fsr4.cpp: AMD's FSR API (FidelityFX SDK 2.4). Only the MIT headers are vendored (third_party/fidelityfx); AMD's signed loader and upscaler DLLs load at run time from RX_FSR4_DIR or beside hookshot.exe. The newest 4.x provider the loader lists is picked explicitly (RDNA 2 and 3 run its INT8 model). LDR, non-linear colour, standard depth. One context per output size, render sizes up to it, so the Resolution row and the game's dynamic resolution need no new context. - Jitter: the game draws without one, so the draws that test or write the scene's depth move by a Halton (2, 3) sub-pixel offset through the viewport, and FSR is told it. The offset is part of the state dyn_pack compares, or a frame whose draws match the last frame's would keep the old one. From Lichii: the phase moves on at the network's pass (where the game's frame ends), not at presents; it is on only while FSR drew the last network pass. - AMD edge line (Lichii, RX 6700 XT): moved up or left, the AMD driver draws nothing into the scene's last column or row, a stale near-white value that became a flickering line in FSR's history. FSR's colour and the motion's depth repeat the column and row before them. Colour going into FSR is cleaned of NaN and Inf and clamped to [0, 1]; the output pass drops NaN and Inf for both upscalers. - FSR history resets when FSR did not draw the last network pass or on a camera cut, not by present count. - Menu: "AMD FSR 4.1" (Off/On, at once; ini key fsr4, RX_FSR4=0/1). Resolution sets what it upscales from (75% Quality, 50% Performance, 100% anti-aliasing only). RX_FSR4_JITTER=0 turns the jitter off. - What changes on native, compared with Lichii: no GPU-time divisor (Hookshot already scales the game's timer, so it keeps full quality), no hunt for the tonemap draw or depth reader (NotRexed#818 takes them where the draws are), no 4/3-only size check. - tests/test_fsr_jitter.py: the jitter is compared and applied, moves on at the network's pass, and the edge repeat is in both passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… images given back - The FSR context is made with FFX_UPSCALE_ENABLE_DYNAMIC_RESOLUTION: the render size changes under it with the Resolution row and the game's dynamic resolution. - vk_fsr4.cpp is Windows only (AMD's signed runtime is), with stubs elsewhere: the Linux build has no LoadLibraryExA. - AMD's dispatches count as work (note_work, vk_work.h), so full_barrier does not leave out the barrier after them as a repeat. - dlss_image gives a replaced image back 120 presents later, as typed_upscale does with its histories, instead of keeping it: DLSS fixes the render size, but FSR can run with Resolution Auto. - The dlss_*.comp headers regenerated at SPIR-V 1.6, as NotRexed#850 makes them. - readme: FSR 4 claims limited to what was tested (RX 6700 XT, INT8). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NVIDIA DLSS
Builds on #849 (Output resolution); until that is merged, this PR also shows its commit.
Optional, for RTX GPUs. DLSS takes over the game's gameplay upscale. The 3D is drawn at the DLSS mode's size, and DLSS scales it up to the game's output using the game's depth and its camera's motion. Movies, menus and the HUD are unchanged. This is ported from zortos293/Lichii (its Streamline loader, camera motion and their shaders), which credits Duck912's Eglantine work.
Menu rows (Graphics tab)
While DLSS is on, the DLSS mode sets the Resolution. The DLSS mode's label and help text follow the Output resolution row as soon as it changes.
NVIDIA files: not included
third_party/streamline/holds NVIDIA Streamline v2.14.16's headers only (MIT,license.txt; noted ingpu/PROVENANCE.md). No NVIDIA binaries are in the repo. At run timesl.interposer.dll,sl.common.dllandsl.dlss.dll(from the Streamline SDK) andnvngx_dlss.dllare loaded from astreamlinefolder beside the game exe. With the launcher layout, that's besidebin\hookshot.exe. Ifnvngx_dlss.dllis missing, the NVIDIA app's copy is used, but only if it is signed by NVIDIA. The interposer and the model must carry a valid NVIDIA Corporation signature (checked with WinVerifyTrust) or they are not loaded. Without these files, DLSS stays off and the game runs as before.Platforms
Windows only. On Linux the DLSS code builds as a stub and the rows say DLSS is unavailable.
Overrides:
RX_DLSS=0/1,RX_DLSS_PRESET=J..M,RX_DLSS_DIR=<folder>; tests:RX_DLSS_DEBUG=<n>.Tested
On an RTX 5090 (Windows 11): the same 140-second gameplay route at every setting below. No crash and no device lost in any run.
With DLSS (3D size -> upscaled to the output)
Also tested at the 4K output: Ultra Performance (1280x720 -> 3840x2160, 4 runs) and DLAA with frame generation 2x. DLSS itself costs about 1.7 ms of GPU time per frame at 4K.
hookshot_vk.dllbuilds with the llvm-mingw version CI uses (20261104), and the DLSS files pass a Linux syntax check.